package com.yanqu.road.server.manager.strongholdwar;

import com.yanqu.road.entity.activity.stronghold.CrossStrongholdEliminateDamage;
import com.yanqu.road.entity.activity.stronghold.CrossStrongholdEliminateDefendPatrons;
import com.yanqu.road.entity.activity.stronghold.CrossStrongholdEliminateUnion;
import com.yanqu.road.entity.activity.stronghold.StrongholdEliminateReport;
import com.yanqu.road.entity.activity.stronghold.config.StrongholdEliminateReportDetail;
import com.yanqu.road.entity.log.cross.stronghold.LogStrongholdEliminateDamage;
import com.yanqu.road.entity.log.cross.stronghold.LogStrongholdMammonHelp;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.union.UnionBaseInfo;
import com.yanqu.road.logic.bussiness.player.activity.CrossStrongholdBusiness;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.activity.StrongholdWarProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.RandomHelper;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossStrongholdEliminateModel {
    private int activityId;
    private int round;
    Map<Integer, CrossStrongholdEliminateUnion> unionMap;
    //6.5 新增使用道具间隔时间
    private Map<Long,Long> mammonHelpLastTimeMap;

    //进攻的  联盟id        玩家id       联盟id  伤害记录
    private Map<String, Map<Long, Map<String, CrossStrongholdEliminateDamage>>> unionAttackRecordMap;
    //防守的联盟id          进攻联盟id    进攻的玩家id    伤害记录
    private Map<String, Map<String, Map<Long, CrossStrongholdEliminateDamage>>> unionDefendRecordMap;

    private StrongholdActivityModel activityModel;

    private final Object ALL_LOCK = new Object();

    private static RandomHelper randomHelper = new RandomHelper();

    public CrossStrongholdEliminateModel(StrongholdActivityModel activityModel, int activityId, int round, Map<Integer, CrossStrongholdEliminateUnion> unionMap, Map<String, Map<Long, Map<String, CrossStrongholdEliminateDamage>>> damageRecordMap) {
        this.activityId = activityId;
        this.round = round;
        this.unionMap = unionMap;
        this.activityModel = activityModel;
        unionAttackRecordMap = damageRecordMap;
        unionDefendRecordMap = new ConcurrentHashMap<>();
        //6.5 新增使用道具间隔时间
        this.mammonHelpLastTimeMap = new ConcurrentHashMap<>();

        for (Map<Long, Map<String, CrossStrongholdEliminateDamage>> mapMap : damageRecordMap.values()) {
            for (Map<String, CrossStrongholdEliminateDamage> damageMap : mapMap.values()) {
                for (CrossStrongholdEliminateDamage damage : damageMap.values()) {
                    addToDefendDamageMap(damage);
                }
            }
        }
        checkUnionMapSortList();
    }

    /**
     * 检查是否所有联盟都生成了各自的排序列表
     */
    private void checkUnionMapSortList() {
        int qualifyNum = CrossStrongholdActivityMgr.getQualifyNum(activityId);
        for (CrossStrongholdEliminateUnion union : unionMap.values()) {
            if (union.getSortList() == null || union.getSortList().size() < qualifyNum) {
                union.setSortList(CrossStrongholdActivityMgr.getRandomSortList(activityId));
            }
        }
    }

    public AttackUnionResult attack(long attackUserId, UserBaseInfo attackUserBaseInfo, int patronsId, BigInteger damage, int id) {
        synchronized (ALL_LOCK) {
            long attackServerId = attackUserBaseInfo.getServerId();
            String attackUnionUid = attackUserBaseInfo.getUnionUid();
            CrossStrongholdEliminateUnion attackUnion = getUnion(attackServerId, attackUnionUid);
            if (attackUnion == null) {
                return new AttackUnionResult(GameErrorCode.E_STRONGHOLD_ELIMINATE_BEEN_BEATED);
            }
            if (attackUnion.getId() == id) {
                //别打自己
                return new AttackUnionResult(GameErrorCode.E_STRONGHOLD_ATTACK_SELF);
            }
            CrossStrongholdEliminateUnion enemyUnion = unionMap.get(id);
            if (enemyUnion == null) {
                return new AttackUnionResult(GameErrorCode.E_STRONGHOLD_ELIMINATE_ENEMY_BEEN_BEATED);
            }
           /* if (attackUnion.getCurBlood().compareTo(BigInteger.ZERO) <= 0) {
                //己方联盟血量为0
                return new AttackUnionResult(GameErrorCode.E_STRONGHOLD_ELIMINATE_BEEN_BEATED);
            }*/
            if (enemyUnion.getCurBlood().compareTo(BigInteger.ZERO) <= 0) {
                //对方联盟血量为0
                return new AttackUnionResult(GameErrorCode.E_STRONGHOLD_ELIMINATE_ENEMY_BEEN_BEATED);
            }
            CrossStrongholdEliminateDefendPatrons defendPatrons = enemyUnion.getCurDefendPatrons();
            if (defendPatrons == null) {
                return new AttackUnionResult(GameErrorCode.E_STRONGHOLD_ELIMINATE_ENEMY_BEEN_BEATED);
            }
            AttackResult result = realAttack(attackUserId, attackUserBaseInfo, attackUnion, enemyUnion, damage, false);
            addAttackLog(attackUserId, patronsId, result.getDefendPatrons(), result.getTotalDamage(), result.getKillNum() > 0);
            return new AttackUnionResult(enemyUnion.getCurDefendPatrons(), result.getKillNum(), enemyUnion, result.getTotalDamage().toString());
        }
    }

    private void rankChange(CrossStrongholdEliminateUnion union, boolean attack) {
        if (union.getCurBlood().compareTo(BigInteger.ZERO) > 0 || !attack) {
            // 如果商会血量大于0 或者处于防守 更新积分
            activityModel.changeEliminateScore(union.getUnionUid(), union.getUnionBaseInfo(), union.getTotalDamage(), union.getCurBlood(), union.getTotalBlood());
        }
    }

    private void addDamageRecord(UserBaseInfo attackUserBaseInfo, long attackUserId, long enemyServerId, String enemyUnionUid, BigInteger damage) {
        synchronized (unionAttackRecordMap) {
            long attackServerId = attackUserBaseInfo.getServerId();
            String attackUnionUid = attackUserBaseInfo.getUnionUid();
            CrossStrongholdEliminateDamage damageRecord = getDamageRecord(attackServerId, attackUnionUid, attackUserId, enemyServerId, enemyUnionUid);
            if (damageRecord == null) {
                damageRecord = new CrossStrongholdEliminateDamage();
                damageRecord.setActivityId(activityId);
                damageRecord.setRound(round);
                damageRecord.setServerId(attackServerId);
                damageRecord.setUnionUid(attackUnionUid);
                damageRecord.setUserId(attackUserId);
                damageRecord.setUserBaseInfo(attackUserBaseInfo);
                damageRecord.setEnemyServerId(enemyServerId);
                damageRecord.setEnemyUnionUid(enemyUnionUid);
                damageRecord.setDamage(BigInteger.ZERO);
                damageRecord.setInsertOption();
                addToAttackDamageMap(damageRecord);
                addToDefendDamageMap(damageRecord);
            }
            damageRecord.setDamage(damageRecord.getDamage().add(damage));
        }
    }

    private void addToDefendDamageMap(CrossStrongholdEliminateDamage damageRecord) {
        long serverId = damageRecord.getServerId();
        String unionUid = damageRecord.getUnionUid();
        long userId = damageRecord.getUserId();
        long enemyServerId = damageRecord.getEnemyServerId();
        String enemyUnionUid = damageRecord.getEnemyUnionUid();

        Map<String, Map<Long, CrossStrongholdEliminateDamage>> attackUnionMap = unionDefendRecordMap.get(enemyUnionUid);
        if (attackUnionMap == null) {
            attackUnionMap = new ConcurrentHashMap<>(16);
            unionDefendRecordMap.put(enemyUnionUid, attackUnionMap);
        }

        Map<Long, CrossStrongholdEliminateDamage> damageMap = attackUnionMap.get(unionUid);
        if (damageMap == null) {
            damageMap = new ConcurrentHashMap<>();
            attackUnionMap.put(unionUid, damageMap);
        }
        damageMap.put(userId, damageRecord);
    }

    private CrossStrongholdEliminateDamage getDamageRecord(long attackServerId, String attackUnionUid, long attackUserId, long enemyServerId, String enemyUnionUid) {

        Map<Long, Map<String, CrossStrongholdEliminateDamage>> attackUserMap = unionAttackRecordMap.get(attackUnionUid);
        if (attackUserMap == null) {
            return null;
        }
        Map<String, CrossStrongholdEliminateDamage> enemyServerMap = attackUserMap.get(attackUserId);
        if (enemyServerMap == null) {
            return null;
        }

        return enemyServerMap.get(enemyUnionUid);
    }

    private void addToAttackDamageMap(CrossStrongholdEliminateDamage damageRecord) {
        long serverId = damageRecord.getServerId();
        String unionUid = damageRecord.getUnionUid();
        long userId = damageRecord.getUserId();

        Map<Long, Map<String, CrossStrongholdEliminateDamage>> attackUserMap = unionAttackRecordMap.get(unionUid);
        if (attackUserMap == null) {
            attackUserMap = new ConcurrentHashMap<>(16);
            unionAttackRecordMap.put(unionUid, attackUserMap);
        }
        Map<String, CrossStrongholdEliminateDamage> enemyServerMap = attackUserMap.get(damageRecord.getUserId());
        if (enemyServerMap == null) {
            enemyServerMap = new ConcurrentHashMap<>();
            attackUserMap.put(damageRecord.getUserId(), enemyServerMap);
        }

        enemyServerMap.put(damageRecord.getEnemyUnionUid(), damageRecord);
    }

    private CrossStrongholdEliminateUnion getUnion(long serverId, String unionUid) {
        return findEliminateUnion(serverId, unionUid);
    }

    public void save() {
        for (Map<Long, Map<String, CrossStrongholdEliminateDamage>> mapMap : new ArrayList<>(unionAttackRecordMap.values())) {
            for (Map<String, CrossStrongholdEliminateDamage> damageMap : new ArrayList<>(mapMap.values())) {
                for (CrossStrongholdEliminateDamage damage : new ArrayList<>(damageMap.values())) {
                    if (damage.isInsertOption()) {
                        CrossStrongholdBusiness.addEliminateDamageRecord(damage);
                    } else if (damage.isUpdateOption()) {
                        CrossStrongholdBusiness.updateEliminateDamageRecord(damage);
                    }
                }
            }
        }

        for (CrossStrongholdEliminateUnion union : unionMap.values()) {
            if (union.isInsertOption()) {
                CrossStrongholdBusiness.addEliminateUnion(union);
            } else if (union.isUpdateOption()) {
                CrossStrongholdBusiness.updateEliminateUnion(union);

            }

            List<CrossStrongholdEliminateDefendPatrons> defendPatronsList = union.getDefendPatronsList();
            if (defendPatronsList != null) {
                for (CrossStrongholdEliminateDefendPatrons patrons : defendPatronsList) {
                    if (patrons.isInsertOption()) {
                        CrossStrongholdBusiness.addEliminatePatrons(patrons);
                    } else if (patrons.isUpdateOption()) {
                        CrossStrongholdBusiness.updateEliminatePatrons(patrons);
                    }
                }
            }
        }
    }

    public void uploadUnionBase(long serverId, List<CrossStrongholdEliminateUnion> eliminateUnions) {
        synchronized (unionMap) {
            for (CrossStrongholdEliminateUnion union : eliminateUnions) {
                CrossStrongholdEliminateUnion eliminateUnion = findEliminateUnion(serverId, union.getUnionUid());
                if (eliminateUnion == null) {
                    eliminateUnion = new CrossStrongholdEliminateUnion();
                    eliminateUnion.setServerId(union.getUnionBaseInfo().getServerId());
                    eliminateUnion.setActivtyId(activityId);
                    eliminateUnion.setUnionUid(union.getUnionUid());
                    eliminateUnion.setInsertOption();
                    List<Integer> idList = getUnionIdList();
                    int id = CrossStrongholdActivityMgr.getRandomId(activityId, idList);
                    eliminateUnion.setId(id);
                    eliminateUnion.setRound(round);
                    eliminateUnion.setSortList(CrossStrongholdActivityMgr.getRandomSortList(activityId));
                    unionMap.put(eliminateUnion.getId(), eliminateUnion);
                }
                eliminateUnion.setStar(union.getStar());
                eliminateUnion.setUnionBaseInfo(union.getUnionBaseInfo());
                for (CrossStrongholdEliminateDefendPatrons patrons : union.getDefendPatronsList()) {
                    patrons.setRound(round);
                    CrossStrongholdEliminateDefendPatrons defendPatrons = eliminateUnion.getDefendPatrons(patrons.getUserId(), patrons.getPatronsIndex());
                    if (defendPatrons == null) {
                        patrons.setInsertOption();
                        eliminateUnion.addSinglePatrons(patrons);
                    } else {
                        defendPatrons.setUserBaseInfo(patrons.getUserBaseInfo());
                        defendPatrons.setEarnSpeed(patrons.getEarnSpeed());
                        defendPatrons.setCurBlood(patrons.getCurBlood());
                        defendPatrons.setTotalBlood(patrons.getTotalBlood());
                        defendPatrons.setPatrons(patrons.getPatrons());
                        defendPatrons.setPatronsIndex(patrons.getPatronsIndex());
                    }
                }
                BigInteger total = BigInteger.ZERO;
                int num = 0;
                for (CrossStrongholdEliminateDefendPatrons patrons : eliminateUnion.getDefendPatronsList()) {
                    if (patrons.getEarnSpeed().compareTo(BigInteger.ZERO) > 0) {
                        total = total.add(patrons.getPatrons().getAddAbility());
                        num++;
                    }
                }
                if (num > 0) {
                    BigInteger blood = total.divide(BigInteger.valueOf(num));
                    for (CrossStrongholdEliminateDefendPatrons patrons : eliminateUnion.getDefendPatronsList()) {
                        if (patrons.getEarnSpeed().compareTo(BigInteger.ZERO) > 0) {
                            patrons.setCurBlood(new BigInteger(blood.toString()));
                            patrons.setTotalBlood(new BigInteger(blood.toString()));
                        }
                    }
                }

                /*for (CrossStrongholdEliminateDefendPatrons patrons : eliminateUnion.getDefendPatronsList()) {
                    int patronsIndex = patrons.getPatronsIndex();
                    long userId = patrons.getUserId();
                    boolean hasPatrons = false;
                    for (CrossStrongholdEliminateDefendPatrons defendPatrons : union.getDefendPatronsList()) {
                        if (defendPatrons.getPatronsIndex() == patronsIndex && userId == defendPatrons.getUserId()) {
                            hasPatrons = true;
                        }
                    }
                    if (!hasPatrons) {
                        patrons.setCurBlood(BigInteger.ZERO);
                        patrons.setTotalBlood(BigInteger.ZERO);
                        patrons.setEarnSpeed(BigInteger.ZERO);
                    }
                }*/
            }
        }
    }

    private List<Integer> getUnionIdList() {
        List<Integer> list = new ArrayList<>();
        for (CrossStrongholdEliminateUnion union : unionMap.values()) {
            list.add(union.getId());
        }
        return list;
    }

    public CrossStrongholdEliminateUnion findEliminateUnion(long serverId, String unionId) {
        for (CrossStrongholdEliminateUnion eliminateUnion : unionMap.values()) {
            if (eliminateUnion.getUnionUid().equals(unionId)) {
                return eliminateUnion;
            }
        }
        return null;
    }

    /**
     * 更新联盟信息
     */
    public void updateEliminateUnion(String unionId, UnionBaseInfo unionBaseInfo) {
        synchronized (unionMap) {
            for (CrossStrongholdEliminateUnion eliminateUnion : unionMap.values()) {
                if (unionId.equals(eliminateUnion.getUnionUid())) {
                    eliminateUnion.setUnionBaseInfo(unionBaseInfo);
                }
            }
        }
    }

    public List<CrossStrongholdEliminateUnion> getEliminateUnionList() {
        return new ArrayList<>(unionMap.values());
    }

    public CrossStrongholdEliminateUnion getUnionById(int id) {
        return unionMap.get(id);
    }

    public Map<String, StrongholdEliminateReport> getEliminateReport(int id, int type) {
        CrossStrongholdEliminateUnion union = getUnionById(id);
        long serverId = union.getServerId();
        String unionUid = union.getUnionUid();
        Map<String, StrongholdEliminateReport> reportMap = new HashMap<>();
        if (type == 1) {
            //进攻
            if (unionAttackRecordMap != null) {
                Map<Long, Map<String, CrossStrongholdEliminateDamage>> userDamageMap = unionAttackRecordMap.get(unionUid);
                if (userDamageMap != null) {
                    for (Map<String, CrossStrongholdEliminateDamage> damageMap : new ArrayList<>(userDamageMap.values())) {
                        for (CrossStrongholdEliminateDamage damage : new ArrayList<>(damageMap.values())) {
                            String enemyUnionUid = damage.getEnemyUnionUid();
                            StrongholdEliminateReport report = reportMap.get(enemyUnionUid);
                            if (report == null) {
                                report = new StrongholdEliminateReport();
                                report.setUnionId(enemyUnionUid);
                                CrossStrongholdEliminateUnion eliminateUnion = findEliminateUnion(damage.getEnemyServerId(), enemyUnionUid);
                                report.setUnionBaseInfo(eliminateUnion.getUnionBaseInfo());
                                reportMap.put(enemyUnionUid, report);
                            }
                            report.setTotalDamage(report.getTotalDamage().add(damage.getDamage()));
                        }
                    }
                    for (StrongholdEliminateReport report : reportMap.values()) {
                        BigInteger totalDamage = report.getTotalDamage();
                        CrossStrongholdEliminateUnion eliminateUnion = findEliminateUnion(report.getUnionBaseInfo().getServerId(), report.getUnionId());
                        int damageRate = totalDamage.multiply(BigInteger.valueOf(10000)).divide(eliminateUnion.getTotalBlood()).intValue();
                        if (damageRate == 0) {
                            damageRate = 1;
                        } else if (damageRate >= 10000) {
                            damageRate = 10000;
                        }
                        report.setDamageRate(damageRate);
                    }
                }
            }
        } else {
            //防守
            if (unionDefendRecordMap != null) {
                Map<String, Map<Long, CrossStrongholdEliminateDamage>> mapMap = unionDefendRecordMap.get(unionUid);
                if (mapMap != null) {
                    for (Map<Long, CrossStrongholdEliminateDamage> damageMap : mapMap.values()) {
                        for (CrossStrongholdEliminateDamage damage : damageMap.values()) {
                            String enemyUnionUid = damage.getUnionUid();
                            StrongholdEliminateReport report = reportMap.get(enemyUnionUid);
                            if (report == null) {
                                report = new StrongholdEliminateReport();
                                report.setUnionId(enemyUnionUid);
                                CrossStrongholdEliminateUnion eliminateUnion = findEliminateUnion(damage.getServerId(), enemyUnionUid);
                                report.setUnionBaseInfo(eliminateUnion.getUnionBaseInfo());
                                reportMap.put(enemyUnionUid, report);
                            }
                            report.setTotalDamage(report.getTotalDamage().add(damage.getDamage()));
                        }
                    }
                    for (StrongholdEliminateReport report : reportMap.values()) {
                        BigInteger totalDamage = report.getTotalDamage();
                        int damageRate = totalDamage.multiply(BigInteger.valueOf(10000)).divide(union.getTotalBlood()).intValue();
                        if (damageRate == 0) {
                            damageRate = 1;
                        } else if (damageRate >= 10000) {
                            damageRate = 10000;
                        }
                        report.setDamageRate(damageRate);

                    }
                }
            }

        }
        return reportMap;
    }

    public List<StrongholdEliminateReportDetail> getEliminateReportDetail(int id, int type, int id2) {
        List<StrongholdEliminateReportDetail> detailList = new ArrayList<>();
        CrossStrongholdEliminateUnion union = getUnionById(id);
        long serverId = union.getServerId();
        String unionUid = union.getUnionUid();
        CrossStrongholdEliminateUnion union2 = getUnionById(id2);
        if (type == 1) {
            Map<Long, Map<String, CrossStrongholdEliminateDamage>> longMapMap = unionAttackRecordMap.get(unionUid);
            if (longMapMap == null) {
                return detailList;
            }
            for (Map<String, CrossStrongholdEliminateDamage> damageMap : new ArrayList<>(longMapMap.values())) {
                CrossStrongholdEliminateDamage damage = damageMap.get(union2.getUnionUid());
                if (damage != null) {
                    StrongholdEliminateReportDetail detail = new StrongholdEliminateReportDetail();
                    detail.setNickName(damage.getUserBaseInfo().getNickName());
                    detail.setDamage(damage.getDamage());
                    detailList.add(detail);
                }
            }
        } else {
            Map<String, Map<Long, CrossStrongholdEliminateDamage>> longMapMap = unionDefendRecordMap.get(unionUid);
            if (longMapMap == null) {
                return detailList;
            }
            Map<Long, CrossStrongholdEliminateDamage> damageMap = longMapMap.get(union2.getUnionUid());
            if (damageMap == null) {
                return detailList;
            }
            for (CrossStrongholdEliminateDamage damage : damageMap.values()) {
                StrongholdEliminateReportDetail detail = new StrongholdEliminateReportDetail();
                detail.setNickName(damage.getUserBaseInfo().getNickName());
                detail.setDamage(damage.getDamage());
                detailList.add(detail);
            }
        }
        return detailList;
    }

    /**
     * @param damage 攻击伤害（不能被修引用。原逻辑被修改了）
     * @param attackFull 是否打满伤害
     * @return
     */
    private AttackResult realAttack(long attackUserId, UserBaseInfo attackUserBaseInfo, CrossStrongholdEliminateUnion attackUnion, CrossStrongholdEliminateUnion enemyUnion, BigInteger damage,
                                    boolean attackFull) {
        int killNum = 0;
        BigInteger totalDamage = BigInteger.ZERO;
        int attackUnionNum = 0;
        boolean isAttack = false;
        CrossStrongholdEliminateDefendPatrons defendPatrons = null;
        //可以造成的伤害
        BigInteger canDamage = damage;

        if (enemyUnion.getCurBlood().compareTo(BigInteger.ZERO) > 0) {
            isAttack = true;
            defendPatrons = enemyUnion.getCurDefendPatrons();
            while (canDamage.compareTo(BigInteger.ZERO) > 0 && defendPatrons != null){
                BigInteger realDamage = canDamage;
                if (realDamage.compareTo(defendPatrons.getCurBlood()) >= 0) {
                    realDamage = new BigInteger(defendPatrons.getCurBlood().toString());
                    killNum++;
                }
                enemyUnion.setLastFightTime(System.currentTimeMillis());
                totalDamage = totalDamage.add(realDamage);
                defendPatrons.setCurBlood(defendPatrons.getCurBlood().subtract(realDamage));
                if (attackUnion.getCurBlood().compareTo(BigInteger.ZERO) > 0) {
                    // 商会还存在 才计算总伤害
                    attackUnion.addTotalDamage(realDamage);
                }
                rankChange(attackUnion, true);
                rankChange(enemyUnion, false);
                // 生成伤害记录
                addDamageRecord(attackUserBaseInfo, attackUserId, enemyUnion.getServerId(), enemyUnion.getUnionUid(), realDamage);
                canDamage = canDamage.subtract(realDamage);
                if(!attackFull){
                    //不打满的情况下，退出
                    break;
                }
                defendPatrons = enemyUnion.getCurDefendPatrons();
            }
        }
        if (isAttack) {
            attackUnionNum += 1;
        }
        AttackResult result = new AttackResult(killNum, totalDamage, attackUnionNum);
        result.setDefendPatrons(defendPatrons);
        noticeMyUnionFailed(enemyUnion);
        noticeAllOtherUnionFailed(attackUnion);
        activityModel.addUserRoungDamage(round, attackUnion, attackUserId, totalDamage, attackUserBaseInfo);
        return result;

    }

    private void noticeAllOtherUnionFailed(CrossStrongholdEliminateUnion attackUnion) {
        boolean allFailed = true;
        for (CrossStrongholdEliminateUnion union : unionMap.values()) {
            if (union.getUnionUid().equals(attackUnion.getUnionUid())) {
                continue;
            }
            if (union.getCurBlood().compareTo(BigInteger.ZERO) > 0) {
                allFailed = false;
                break;
            }
        }
        if (allFailed) {
            StrongholdWarProto.CrossStrongholdEliminateUnionStatusRespMsg.Builder resp = StrongholdWarProto.CrossStrongholdEliminateUnionStatusRespMsg.newBuilder();
            resp.setActivityId(activityId);
            resp.setUnionId(attackUnion.getUnionUid());
            resp.setExist(false);
            resp.setUserId(0);
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(GameProtocol.S_CROSS_STRONGHOLD_ELIMINATE_UNION_STATUS, resp);
            MessageHelper.sendPacket(attackUnion.getServerId(), 0, pbMsg);
        }
    }

    private void noticeMyUnionFailed(CrossStrongholdEliminateUnion enemyUnion) {
        if (enemyUnion.getCurBlood().compareTo(BigInteger.ZERO) <= 0) {
            StrongholdWarProto.CrossStrongholdEliminateUnionStatusRespMsg.Builder resp = StrongholdWarProto.CrossStrongholdEliminateUnionStatusRespMsg.newBuilder();
            resp.setActivityId(activityId);
            resp.setUnionId(enemyUnion.getUnionUid());
            resp.setExist(false);
            resp.setUserId(0);
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(GameProtocol.S_CROSS_STRONGHOLD_ELIMINATE_UNION_STATUS, resp);
            MessageHelper.sendPacket(enemyUnion.getServerId(), 0, pbMsg);
        }
    }

    private void addAttackLog(long attackUserId, int patronsId, CrossStrongholdEliminateDefendPatrons defendPatrons, BigInteger damage, boolean isKill) {
        // fightTimes和reward之前也没有相关数据
        CrossAutoLogMgr.add(new LogStrongholdEliminateDamage(
                activityId,
                attackUserId,
                patronsId,
                0,
                damage.toString(),
                isKill,
                defendPatrons.getUnionUid(),
                defendPatrons.getUserId(),
                defendPatrons.getPatrons().getPatronsId(),
                ""
        ));
    }

    private CrossStrongholdEliminateUnion findEliminateUnion(String unionId) {
        for (CrossStrongholdEliminateUnion union : unionMap.values()) {
            if (union.getUnionUid().equals(unionId)) {
                return union;
            }
        }
        return null;
    }

    /**
     * 设置最后一次使用财神助力的攻击时间
     * @param userId
     */
    public void setLastMammonHelpTime(long userId){
        synchronized (mammonHelpLastTimeMap){
            mammonHelpLastTimeMap.put(userId,System.currentTimeMillis());
        }
    }


    /**
     * 检测玩家财神助力是否过于频繁
     * @param userId
     * @return
     */

    public boolean checkMammonHelpTooOften(long userId){
        synchronized (mammonHelpLastTimeMap){
            if (mammonHelpLastTimeMap.containsKey(userId)){
                long lastTime = mammonHelpLastTimeMap.get(userId);
                if (System.currentTimeMillis() - lastTime < CrossStrongholdActivityMgr.getMammonHelpItemCd(activityId)){
                    return true;
                }
            }
        }
        return false;
    }



    public MammonHelpResult mammonHelp(long userId, UserBaseInfo attackUserBaseInfo, int configType, int mammonType, List<Integer> idList, BigInteger totalDamage, int randomTimes) {
        synchronized (ALL_LOCK) {
            String myUnionId = attackUserBaseInfo.getUnionUid();
            CrossStrongholdEliminateUnion myUnion = findEliminateUnion(myUnionId);
           /* if (myUnion == null || myUnion.getCurBlood().compareTo(BigInteger.ZERO) <= 0) {
                //本方已被击败
                return new MammonHelpResult(GameErrorCode.E_STRONGHOLD_ELIMINATE_BEEN_BEATED);
            }*/
            List<CrossStrongholdEliminateUnion> tempUnionList = new ArrayList<>();
            boolean tooOften = checkMammonHelpTooOften(userId);
            if (tooOften){
                return new MammonHelpResult(GameErrorCode.E_STRONGHOLD_MAMMON_HELP_TOO_OFTEN);
            }

            if (mammonType == 1) {
                return attackAppointUnion(myUnion, userId, attackUserBaseInfo, idList, totalDamage);
            } else {
                int totalKillNum = 0;
                BigInteger resultDamage = BigInteger.ZERO;
                int totalAttackNum = 0;

                List<String> attackUnionList = new ArrayList<>();
                boolean isAll = false;
                Map<Integer, BigInteger> unionDamageMap = new HashMap<>();
                configType = 2;
                if (configType == 2) {
                    //随机找N个联盟
                    Set<String> attackUnionSet = new HashSet<>();
                    List<CrossStrongholdEliminateUnion> unionList = findAllOtherUnion(myUnionId);
                    if (unionList.size() == 0) {
                        return new MammonHelpResult(GameErrorCode.E_STRONGHOLD_ELIMINATE_NO_ANY_UNION);
                    }
                    for (int i = 0; i < randomTimes; i++) {
                        unionList = findAllOtherUnion(myUnionId);
                        if (unionList.isEmpty()) {
                            break;
                        }
                        int index = randomHelper.next(0, unionList.size());
                        CrossStrongholdEliminateUnion union = unionList.get(index);
                        attackUnionSet.add(union.getUnionUid());
                        AttackResult result = realAttack(userId, attackUserBaseInfo, myUnion, union, totalDamage, true);
                        resultDamage = resultDamage.add(result.getTotalDamage());
                        totalKillNum += result.getKillNum();
                        attackUnionList.add(union.getUnionUid());
                        if (unionDamageMap.containsKey(union.getId())) {
                            unionDamageMap.put(union.getId(), unionDamageMap.get(union.getId()).add(result.getTotalDamage()));
                        } else {
                            unionDamageMap.put(union.getId(), new BigInteger(result.getTotalDamage().toString()));
                        }
                    }
                    totalAttackNum = attackUnionSet.size();
                }/* else {
                    List<CrossStrongholdEliminateUnion> eliminateUnions = findAllOtherUnion(myUnionId);
                    if (eliminateUnions.size() == 0) {
                        return new MammonHelpResult(GameErrorCode.E_STRONGHOLD_ELIMINATE_NO_ANY_UNION);
                    }
                    isAll = true;
                    tempUnionList.addAll(eliminateUnions);
                    totalDamage = totalDamage.divide(BigInteger.valueOf(tempUnionList.size()));
                    for (CrossStrongholdEliminateUnion union : tempUnionList) {
                        AttackResult result = realAttack(userId, attackUserBaseInfo, myUnion, union, totalDamage);
                        totalKillNum += result.getKillNum();
                        resultDamage = resultDamage.add(result.getTotalDamage());
                        totalAttackNum += result.getAttackUnionNum();
                        attackUnionList.add(union.getUnionUid());
                        if (unionDamageMap.containsKey(union.getId())) {
                            unionDamageMap.put(union.getId(), unionDamageMap.get(union.getId()).add(result.getTotalDamage()));
                        } else {
                            unionDamageMap.put(union.getId(), new BigInteger(result.getTotalDamage().toString()));
                        }
                    }
                }*/
                //已经再realAttack里调用过了，这里不能重复调用
//                activityModel.addUserRoungDamage(round, myUnion, userId, resultDamage, attackUserBaseInfo);
                addMammonLog(userId, configType, mammonType, resultDamage, attackUnionList, isAll);
                //记录最后一次使用财神助力的时间
                setLastMammonHelpTime(userId);
                return new MammonHelpResult(totalKillNum, totalAttackNum, resultDamage, unionDamageMap);
            }
        }
    }

    /**
     * 攻击指定联盟
     *
     * @param myUnion
     * @param userId
     * @param attackUserBaseInfo
     * @param idList
     * @param totalDamage
     * @return
     */
    private MammonHelpResult attackAppointUnion(CrossStrongholdEliminateUnion myUnion, long userId, UserBaseInfo attackUserBaseInfo, List<Integer> idList, BigInteger totalDamage) {
        List<CrossStrongholdEliminateUnion> unionList = new ArrayList<>();
        List<String> attackUnionList = new ArrayList<>();
        String unionName = "";
        for (int id : idList) {
            CrossStrongholdEliminateUnion union = getUnionById(id);
            if (union == null || union.getCurBlood().compareTo(BigInteger.ZERO) <= 0) {
                return new MammonHelpResult(GameErrorCode.E_STRONGHOLD_ELIMINATE_ENEMY_BEEN_BEATED);
            }
            if (myUnion.getId() == id) {
                return new MammonHelpResult(GameErrorCode.E_STRONGHOLD_ATTACK_SELF);
            }
            unionList.add(union);
            attackUnionList.add(union.getUnionUid());
            unionName = union.getUnionBaseInfo().getUnionName();
        }

        int totalKillNum = 0;
        BigInteger resultDamage = BigInteger.ZERO;
        int totalAttackNum = 0;

        Map<Integer, BigInteger> unionDamageMap = new HashMap<>();
        for (CrossStrongholdEliminateUnion union : unionList) {
            BigInteger attackDamage = totalDamage;
            while (attackDamage.compareTo(BigInteger.ZERO) > 0 && union.getCurBlood().compareTo(BigInteger.ZERO) > 0) {
                // 当伤害值还有，且联盟未被击败，继续打
                AttackResult result = realAttack(userId, attackUserBaseInfo, myUnion, union, attackDamage, false);
                BigInteger realDamage = result.getTotalDamage();
                attackDamage = attackDamage.subtract(realDamage);
                if (unionDamageMap.containsKey(union.getId())) {
                    unionDamageMap.put(union.getId(), unionDamageMap.get(union.getId()).add(realDamage));
                } else {
                    unionDamageMap.put(union.getId(), new BigInteger(realDamage.toString()));
                }
                totalKillNum += result.getKillNum();
                resultDamage = resultDamage.add(realDamage);
            }
            totalAttackNum += 1;
        }
//        activityModel.addUserRoungDamage(round, myUnion, userId, resultDamage, attackUserBaseInfo);
        addMammonLog(userId, 2, 1, resultDamage, attackUnionList, false);
        MammonHelpResult result = new MammonHelpResult(totalKillNum, totalAttackNum, resultDamage, unionDamageMap);
        result.setUnionName(unionName);
        //记录最后一次使用财神助力的时间
        setLastMammonHelpTime(userId);
        return result;
    }

    private void addMammonLog(long userId, int bigType, int childType, BigInteger totalDamage, List<String> unionList, boolean isAll) {
        CrossAutoLogMgr.add(new LogStrongholdMammonHelp(
                activityId,
                userId,
                bigType,
                childType,
                unionList,
                totalDamage.toString(),
                isAll
        ));
    }

    private List<CrossStrongholdEliminateUnion> findAllOtherUnion(String myUnionId) {
        List<CrossStrongholdEliminateUnion> tempUnionList = new ArrayList<>();
        for (CrossStrongholdEliminateUnion union : unionMap.values()) {
            if (!union.getUnionUid().equals(myUnionId) && union.getCurBlood().compareTo(BigInteger.ZERO) > 0) {
                //不是本方 且还有血量
                tempUnionList.add(union);
            }
        }
        return tempUnionList;
    }

    public List<CrossStrongholdEliminateDefendPatrons> getDefendPatronsByUnionId(String unionId) {
        List<CrossStrongholdEliminateDefendPatrons> list = new ArrayList<>();
        for (CrossStrongholdEliminateUnion union : new ArrayList<>(unionMap.values())) {
            if (union.getUnionUid().equals(unionId)) {
                list.addAll(union.getDefendPatronsList());
            }
        }
        return list;
    }
}
